package com.techsoul.module.marketing.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.techsoul.common.core.exception.BusinessException;
import com.techsoul.common.core.exception.ParamException;
import com.techsoul.common.core.pojo.vo.UserVo;
import com.techsoul.common.core.util.ServletUtils;
import com.techsoul.common.core.util.bean.BeanUtils;
import com.techsoul.common.core.util.collection.ListUtils;
import com.techsoul.common.core.util.id.IdWorker;
import com.techsoul.common.security.service.TokenService;
import com.techsoul.module.marketing.mapper.CouponMapper;
import com.techsoul.module.marketing.pojo.entity.Coupon;
import com.techsoul.module.marketing.pojo.param.CouponActivitySaveParam;
import com.techsoul.module.marketing.pojo.param.CouponSaveParam;
import com.techsoul.module.marketing.pojo.param.CouponSearchParam;
import com.techsoul.module.marketing.pojo.vo.CouponActivityVo;
import com.techsoul.module.marketing.pojo.vo.CouponVo;
import com.techsoul.module.marketing.service.ICouponActivityService;
import com.techsoul.module.marketing.service.ICouponService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Random;

/**
 * 优惠券 Service实现
 * 
 * @author liuen
 * @date 2021-04-26
 */
@Service
@Transactional(readOnly = true)
public class CouponServiceImpl implements ICouponService {

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private CouponMapper mapper;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private ICouponActivityService couponActivityService;

    /**
     * 新增
     * @param params
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public String insert(CouponSaveParam params) {
        UserVo user = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();
        Coupon entity = new Coupon();
        BeanUtils.copyProperties(params, entity);
        entity.setId(idWorker.nextId() + "").preInsert(user.getId());
        this.mapper.insert(entity);
        return entity.getId();
    }

    /**
     * 领取优惠券
     * @param params
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public void receive(CouponSaveParam params) {
        UserVo user = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();

        // 校验优惠券活动
        CouponActivityVo couponActivityVo = couponActivityService.findById(params.getActivityId());
        if (couponActivityVo == null) {
            throw new BusinessException("优惠券活动已关闭");
        }
        if (couponActivityVo.getPublishQty() <= couponActivityVo.getReceivedQty()) {
            throw new BusinessException("优惠券已经领完了");
        }
        Date now = new Date();
        if (now.after(couponActivityVo.getEndTime())) {
            throw new BusinessException("优惠券已过期");
        }
        // 校验用户领取的优惠券数量是否超过限制
        QueryWrapper<Coupon> qw = new QueryWrapper();
        qw.eq("receiver_id", user.getId());
        qw.eq("activity_id", params.getActivityId());
        int count = this.mapper.selectCount(qw);
        if (count >= couponActivityVo.getLimitQty()) {
            throw new BusinessException("您已经领取过该优惠券");
        }
        // 生成领取优惠券历史
        CouponSaveParam couponSaveParam = new CouponSaveParam();
        couponSaveParam.setStoreId(couponActivityVo.getStoreId())
                .setActivityId(couponActivityVo.getId())
                .setActivityName(couponActivityVo.getActivityName())
                .setCouponCode(generateCouponCode(user.getId()))
                .setAmount(couponActivityVo.getAmount())
                .setUseCondition(couponActivityVo.getUseCondition())
                .setStartTime(couponActivityVo.getStartTime())
                .setEndTime(couponActivityVo.getEndTime())
                .setReceiverId(user.getId())
                .setReceiver(user.getNickName())
                .setGetType("1") // 主动领取
                .setStatus("0") // 未使用
                .setRemark(couponActivityVo.getActivityName() + ":满" + couponActivityVo.getUseCondition() + "减" + couponActivityVo.getAmount());
        // 添加优惠券
        this.insert(couponSaveParam);
        // 更新优惠券活动信息
        CouponActivitySaveParam couponActivitySaveParam = new CouponActivitySaveParam();
        BeanUtils.copyProperties(couponActivityVo, couponActivitySaveParam);
        couponActivitySaveParam.setReceivedQty(couponActivityVo.getReceivedQty() + 1); // 领取数量
        couponActivityService.update(couponActivitySaveParam);
    }

    /**
     * 16位优惠码生成：时间戳后8位+4位随机数+用户id后4位
     */
    private String generateCouponCode(String userId) {
        StringBuilder sb = new StringBuilder();
        Long currentTimeMillis = System.currentTimeMillis();
        String timeMillisStr = currentTimeMillis.toString();
        sb.append(timeMillisStr.substring(timeMillisStr.length() - 8));
        for (int i = 0; i < 4; i++) {
            sb.append(new Random().nextInt(10));
        }
        if (userId.length() <= 4) {
            sb.append(String.format("%04d", Integer.valueOf(userId)));
        } else {
            sb.append(userId.substring(userId.length() - 4));
        }
        return sb.toString();
    }

    /**
     * 删除
     * @param id
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public Integer delete(String id) {
        return this.mapper.deleteById(id);
    }

    /**
     * 批量删除
     * @param idList
     */
    @Transactional(readOnly = false)
    @Override
    public Integer batchDelete(List<String> idList) {
        if (ListUtils.isNotEmpty(idList)) {
            return this.mapper.deleteBatchIds(idList);
        } else {
            return 0;
        }
    }

    /**
     * 修改
     * @param params
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public Integer update(CouponSaveParam params) {
        Coupon entityFromDb = this.mapper.selectById(params.getId());
        if (entityFromDb == null) {
            throw new ParamException("id=" + params.getId());
        }
        UserVo user = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();
        BeanUtils.copyProperties(params, entityFromDb);
        entityFromDb.preUpdate(user.getId());
        return this.mapper.updateById(entityFromDb);
    }

    /**
     * 详情
     * @param id
     * @return
     */
    @Override
    public CouponVo findById(String id) {
        return this.mapper.findById(id);
    }

    /**
     * 列表
     * @param params
     * @return
     */
    @Override
    public List<CouponVo> findAll(CouponSearchParam params) {
        return this.mapper.findAll(params);
    }

    /**
     * 列表-分页
     * @param params
     * @param current
     * @param pageSize
     * @return
     */
    @Override
    public IPage<CouponVo> findAll(CouponSearchParam params, Integer current, Integer pageSize) {
        return this.mapper.findAll(new Page<>(current, pageSize), params);
    }

    /**
     * 用户已领取且未使用的优惠券列表
     * @return
     */
    @Override
    public List<CouponVo> userCouponList(CouponSearchParam params) {
        UserVo user = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();
        params.setReceiverId(user.getId());
        return this.mapper.userCouponList(params);
    }

}
